package com.zhiche.wms.service.opbaas.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.lisa.json.JSONUtil;
import com.lisa.syslog.SysLogUtil;
import com.lisa.syslog.model.SysLogDataPo;
import com.lisa.syslog.model.publics.PublicLog;
import com.zhiche.wms.configuration.MyConfigurationProperties;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.InterfaceAddrEnum;
import com.zhiche.wms.core.supports.enums.SystemEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.HttpClientUtil;
import com.zhiche.wms.domain.mapper.opbaas.ExceptionConfigurationMapper;
import com.zhiche.wms.domain.mapper.opbaas.ExceptionRegisterMapper;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegister;
import com.zhiche.wms.domain.model.opbaas.OpDeliveryPoint;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.dto.opbaas.paramdto.CommonConditionParamDTO;
import com.zhiche.wms.dto.opbaas.paramdto.ExceptionIsCanSendDTO;
import com.zhiche.wms.dto.opbaas.resultdto.ExResultDTO;
import com.zhiche.wms.service.opbaas.ExceptionToOTMService;
import com.zhiche.wms.service.opbaas.IDeliveryPointService;
import com.zhiche.wms.service.opbaas.IExceptionConfigurationService;
import com.zhiche.wms.service.opbaas.IExceptionRegisterService;
import com.zhiche.wms.service.utils.CommonMethod;
import com.zhiche.wms.service.utils.OTMCodeMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 异常推送otm
 * </p>
 *
 * @author yzy
 * @since 2018-11-09
 */
@Service
public class ExceptionToOTMServiceImpl implements ExceptionToOTMService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionToOTMServiceImpl.class);

    @Autowired
    private IExceptionRegisterService registerService;

    @Autowired
    private MyConfigurationProperties properties;

    @Autowired
    private IDeliveryPointService deliveryPointService;

    @Autowired
    private ExceptionRegisterMapper exceptionRegisterMapper;
    @Autowired
    private OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    ExceptionConfigurationMapper exceptionConfigurationMapper;

    @Autowired
    IExceptionConfigurationService iExceptionConfigurationService;

    @Override
    public void deleteExceptionToOTM (String[] ids, String code) {
        //code 为1表示wms删除推动otm，为0表示job定时跑任务
    }

    public void isCanSend (CommonConditionParamDTO conditionParamDTO) {
        if (conditionParamDTO == null) {
            throw new BaseException("参数不能为空");
        }
        Map<String, String> condition = conditionParamDTO.getCondition();
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("condition不能为空");
        }
        if (StringUtils.isBlank(condition.get("houseId"))) {
            throw new BaseException("仓库id不能为空");
        }
        if (StringUtils.isBlank(condition.get("lotNo1"))) {
            throw new BaseException("车架号不能为空");
        }

        //查询是否有已调度未发运的指令,只有登记了异常不可发运时走该逻辑
       /* if (TableStatusEnum.STATUS_N.getCode().equals(condition.get("isCanSend"))) {
            shipmentIsCreated(condition.get("lotNo1"));
        }*/

        if (StringUtils.isNotBlank(condition.get("isCanSend"))) {
            String result = null;
            String jsonParam = null;
            String paramIsCanSend = condition.get("isCanSend");
            if (TableStatusEnum.STATUS_N.getCode().equals(paramIsCanSend) || TableStatusEnum.STATUS_Y.getCode().equals(paramIsCanSend)) {
                ExceptionIsCanSendDTO exceptionIsCanSendDTO = setExceptionParam(condition);
                //组装数据给OTM
                jsonParam = JSONObject.toJSONString(exceptionIsCanSendDTO);
                LOGGER.info("异常处理推送otm jsonParam{}", jsonParam);
                result = HttpClientUtil.postJson(properties.getOtmhost() + InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress(), null, jsonParam, properties.getSocketTimeOut());
                LOGGER.info("异常处理推送otm result:{},url:{}", result, properties.getOtmhost() + InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress());
            }
            //记录异常推送日志
            registerService.saveExceptionLog(condition,jsonParam,result);
            if (StringUtils.isNotBlank(result)) {
                JSONObject jsonObject = JSONObject.parseObject(result);
                if (jsonObject.getString("success").equals("true")) {
                    ExceptionRegister exceptionRegister = new ExceptionRegister();
                    exceptionRegister.setOtmStatus(paramIsCanSend);
                    exceptionRegister.setHouseId(condition.get("houseId"));
                    exceptionRegister.setId(condition.get("wms_id"));
                    Wrapper<ExceptionRegister> exceptionRegisterWrapper = new EntityWrapper<>();
                    exceptionRegisterWrapper.eq("vin", condition.get("lotNo1"));
                    registerService.update(exceptionRegister, exceptionRegisterWrapper);
                }
            }
        }
    }

    /**
     * 添加日志记录到日志系统
     */
    public void addSysLogs(String busEventKey, String reqParam, String uri, Integer dataStatus, Integer isSuc, String errCont) {
        new Thread(() -> {
            try {
                if (StringUtils.isNotBlank(busEventKey) && StringUtils.isNotBlank(reqParam)) {
                    String sourceSystem = SystemEnum.WMS.getCode();
                    String targetSystem = SystemEnum.OTM.getCode();
                    // 来源、目标系统表示
                    // 目标API标示
                    String key = sourceSystem + "_" + targetSystem;
                    String fKey = uri + SystemEnum.UNDERLINE.getCode() + busEventKey + SystemEnum.UNDERLINE.getCode() + dataStatus;
                    // 业务相关实体类
                    PublicLog publicLog = new PublicLog(sourceSystem, targetSystem, uri, busEventKey, reqParam, dataStatus, isSuc, 1, errCont);
                    SysLogDataPo sysLogDataPo = new SysLogDataPo(SysLogUtil.PUBLIC_, JSONUtil.toJsonStr(publicLog));
                    SysLogUtil.addSysLogs(key, fKey, sysLogDataPo, Boolean.valueOf(properties.getLogRedisIsTest()));
                }
            } catch (Exception e) {
                LOGGER.error("异常信息回传otm，添加日志异常" + e.getMessage());
            }
        }).start();
    }

    private ExceptionIsCanSendDTO setExceptionParam (Map<String, String> param) {
        ExceptionIsCanSendDTO exceptionIsCanSendDTO = new ExceptionIsCanSendDTO();
        exceptionIsCanSendDTO.setVin(param.get("lotNo1"));
        exceptionIsCanSendDTO.setException_result(param.get("exception_result"));
        exceptionIsCanSendDTO.setException_desc(param.get("exception_desc"));
        exceptionIsCanSendDTO.setPhone_url(param.get("phone_url"));
        exceptionIsCanSendDTO.setCus_order_no(param.get("cus_order_no"));
        exceptionIsCanSendDTO.setWms_id(param.get("wms_id"));
        exceptionIsCanSendDTO.setWork_node(param.get("work_node"));
        exceptionIsCanSendDTO.setRegistrant(param.get("registrant"));
        exceptionIsCanSendDTO.setException_type(param.get("exception_type"));
        if(StringUtils.isNotBlank(param.get("deleted"))){
            exceptionIsCanSendDTO.setException_handle_status(param.get("deleted").equals("Y") ? "已删除" : param.get("exception_handle_status"));
        } else {
            exceptionIsCanSendDTO.setException_handle_status(param.get("exception_handle_status"));
        }
        exceptionIsCanSendDTO.setIs_factory_exception(param.get("is_factory_exception") == null ? "N" : param.get("is_factory_exception"));
        exceptionIsCanSendDTO.setIs_send(param.get("isCanSend"));
        exceptionIsCanSendDTO.setRegister_time(param.get("register_time"));
        exceptionIsCanSendDTO.setOrder_id(queryOrderNo(param.get("lotNo1")));
        exceptionIsCanSendDTO.setOrder_release_xid(param.get("order_release_xid"));
        exceptionIsCanSendDTO.setEstimated_processing_time(param.get("estimatedProcessingTime"));
        exceptionIsCanSendDTO.setDeleted(param.get("deleted") == null ? "N" : param.get("deleted"));
        if(StringUtils.isNotBlank(param.get("remark"))){
            exceptionIsCanSendDTO.setRemark(param.get("remark"));
        }
        return exceptionIsCanSendDTO;
    }

    private String queryOrderNo (String lotNo1) {
        EntityWrapper<OtmOrderRelease> releaseEw = new EntityWrapper<>();
        releaseEw.eq("vin",lotNo1);
        releaseEw.ne("status",TableStatusEnum.STATUS_50.getCode());
        List<OtmOrderRelease> otmOrderReleases = otmOrderReleaseMapper.selectList(releaseEw);
        if(CollectionUtils.isEmpty(otmOrderReleases)){
          throw new BaseException("系统运单号为空，请于ILS系统补发修改！");
        }
        return otmOrderReleases.get(0).getOrderNo();
    }

    /**
     * 如果对应的车架号有已调度未发运的，提示不能标记异常，联系调度取消指令之后再标记异常
     *
     * @param lotNo1 车架号
     */
    private void shipmentIsCreated (String lotNo1) {
        EntityWrapper<OtmOrderRelease> orderEw = new EntityWrapper<>();
        orderEw.eq("status", TableStatusEnum.STATUS_BS_CREATED.getCode());
        orderEw.eq("vin", lotNo1);
        List<OtmOrderRelease> otmOrderReleases = otmOrderReleaseMapper.selectList(orderEw);
        if (CollectionUtils.isNotEmpty(otmOrderReleases)) {
            List<String> orderList = new ArrayList<>();
            for (OtmOrderRelease otmOrderRelease : otmOrderReleases) {
                orderList.add(otmOrderRelease.getCusWaybillNo());
            }
            throw new BaseException("该车架号已调度" + orderList + "请联系调度取消运单后再操作！");
        }
    }

    public String isSend(String vin ,String originName) {
        Wrapper<ExceptionRegister> exceptionRegisterWrapper = new EntityWrapper<>();
        exceptionRegisterWrapper.eq("vin", vin);
        ExceptionRegister exceptionRegister = registerService.selectOne(exceptionRegisterWrapper);
        if (Objects.isNull(exceptionRegister)||StringUtils.isEmpty(exceptionRegister.getOtmStatus())) {
            Wrapper<OpDeliveryPoint> opDeliveryPointWrapper=new EntityWrapper<>();
            opDeliveryPointWrapper.eq("name",originName);
            OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectOne(opDeliveryPointWrapper);
            if (!Objects.isNull(opDeliveryPoint)){
                if (!StringUtils.isEmpty(opDeliveryPoint.getExceShip())&&opDeliveryPoint.getExceShip().equals(TableStatusEnum.STATUS_N.getCode())) {
                    return  TableStatusEnum.STATUS_N.getCode();
                }
                if (!StringUtils.isEmpty(opDeliveryPoint.getExceShip())&&opDeliveryPoint.getExceShip().equals(TableStatusEnum.STATUS_Y.getCode())) {
                    return TableStatusEnum.STATUS_Y.getCode();
                }
            }
        } else {
            return exceptionRegister.getOtmStatus();
        }
        return null;
    }
    /**
     * 返厂维修数据推送OTM
     *
     * @param exceptionRegisters 异常发运表的数据
     * @param vin 车架号
     */
    @Override
    public void serviceFactoryToOTM (List<ExceptionRegister> exceptionRegisters, String vin) {
        Wrapper<ExResultDTO> ew = new EntityWrapper<>();
        ew.eq("a.vin", vin);
        ew.ne("a.status", TableStatusEnum.STATUS_0.getCode());
        List<ExResultDTO> resultDTOS = exceptionRegisterMapper.selectExListDetail(new Page<>(), ew);
        if (CollectionUtils.isNotEmpty(resultDTOS)) {
            for (ExResultDTO exResultDTO : resultDTOS) {
                Map<String, Object> param = new HashMap<>();
                param.put("vin", exResultDTO.getVin());
                param.put("exceptionResult", "返厂维修");
                param.put("exceptionDesc", exResultDTO.getExDescribe());
                param.put("registerTime", CommonMethod.getStringDate(exResultDTO.getRegisterTime()));
                param.put("photoUrl", exResultDTO.getPicKey());
                String jsonParam = JSONObject.toJSONString(param);
                String result = HttpClientUtil.postJson(properties.getOtmhost() + InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress(), null,
                        jsonParam, properties.getSocketTimeOut());
                LOGGER.info("返厂维修推送otm result:{},params:{},url:{}", result, jsonParam, properties.getOtmhost() + InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress());
                JSONObject jsonObject = JSONObject.parseObject(result);
                LOGGER.info("返厂维修推送OTM结果jsonObject：{}", jsonObject);

                //返厂维修异常推送otm，添加日志到redis
               /* if (jsonObject.getString("success").equals("true")) {
                    addSysLogs(exResultDTO.getPicKey(), jsonParam, InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress(), 1, 1, "");
                } else {
                    addSysLogs(exResultDTO.getPicKey(), jsonParam, InterfaceAddrEnum.EXCEPTION_RTF_OTM.getAddress(), 1, 0, jsonObject.getString("message"));
                }*/
            }
        }
    }

    @Override
    public List<CommonConditionParamDTO> setToOtmParam (CommonConditionParamDTO conditionParamDTO) {
        if (null == conditionParamDTO) {
            throw new BaseException("入参不能为空");
        }
        Map<String, String> condition = conditionParamDTO.getCondition();
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("condition不能为空");
        }
        if (StringUtils.isBlank(condition.get("houseId"))) {
            throw new BaseException("仓库id不能为空");
        }
        if (StringUtils.isBlank(condition.get("lotNo1"))) {
            throw new BaseException("车架号不能为空");
        }

        if (StringUtils.isEmpty(condition.get("isCanSend"))) {
            return null;
        }
        /*if(StringUtils.isEmpty(condition.get("orderReleaseGid"))){
            throw new BaseException("系统运单OR号不能为空");
        }*/

        if(StringUtils.isEmpty(condition.get("estimatedProcessingTime"))){
            throw new BaseException("预计处理时间不能为空！");
        }
        List<CommonConditionParamDTO> list = new ArrayList<>();
        //查询异常照片和异常描述
        Wrapper<ExResultDTO> pictureEw = new EntityWrapper<>();
        //pictureEw.eq("a.release_gid",condition.get("orderReleaseGid"));
        pictureEw.eq("a.vin", condition.get("lotNo1"));
        pictureEw.ne("a.status", TableStatusEnum.STATUS_0.getCode());
        pictureEw.ne("a.deal_status",TableStatusEnum.STATUS_50.getCode());
        pictureEw.isNotNull("release_gid");
        List<ExResultDTO> pictureResult = exceptionRegisterMapper.selectExListDetail(new Page<>(), pictureEw);
        if (CollectionUtils.isNotEmpty(pictureResult)) {
            for (ExResultDTO exResultDTO : pictureResult) {
                CommonConditionParamDTO commonConditionParamDTO = new CommonConditionParamDTO();
                Map<String, String> params = new HashMap<>();
                params.put("lotNo1", exResultDTO.getVin());
                params.put("houseId", condition.get("houseId"));
                params.put("vin", exResultDTO.getVin());
                params.put("is_factory_exception", TableStatusEnum.STATUS_N.getCode()); //是否工厂异常
                params.put("wms_id", exResultDTO.getId());
                if(StringUtils.isNotBlank(exResultDTO.getId())){
                    //预计异常处理完成时间
                    ExceptionRegister updateTime = new ExceptionRegister();
                    updateTime.setId(exResultDTO.getId());
                    updateTime.setEstimatedProcessingTime(CommonMethod.stringToDate2(condition.get("estimatedProcessingTime").toString()));
                    exceptionRegisterMapper.updateById(updateTime);
                }
                params.put("cus_order_no", exResultDTO.getOmsOrderNo());
                params.put("exception_result", exResultDTO.getDealType() == null ? "" : OTMCodeMap.EXCEPTION_DEAL_TYPE.get(exResultDTO.getDealType()));//异常处理方式
                params.put("exception_desc", exResultDTO.getExDescribe());//异常描述
                params.put("phone_url", "");
                if (null != exResultDTO) {
                    params.put("phone_url", exResultDTO.getPicKey());
                }
                params.put("work_node", exResultDTO.getTaskNode() == null ? "" : OTMCodeMap.EXCEPTION_TASK_NODE.get(exResultDTO.getTaskNode()));//登记节点
                params.put("registrant", exResultDTO.getRegisterUser());//登记人
                params.put("exception_type", iExceptionConfigurationService.queryNameByCode(exResultDTO.getExLevel3()));//异常类型
                params.put("exception_handle_status", OTMCodeMap.EXCEPTION_DEAL_STATUS.get(exResultDTO.getDealStatus())); //异常处理状态
                params.put("isCanSend", condition.get("isCanSend"));
                params.put("register_time", CommonMethod.getStringDate(exResultDTO.getRegisterTime())); //登记时间
                params.put("order_release_xid", condition.get("orderReleaseGid") == null ? "" : condition.get("orderReleaseGid")); //wms运单号
                params.put("estimatedProcessingTime", condition.get("estimatedProcessingTime")); //异常预计处理时间
                if(StringUtils.isNotBlank(exResultDTO.getRemark())){
                    params.put("remark",exResultDTO.getRemark());
                }
                commonConditionParamDTO.setCondition(params);
                list.add(commonConditionParamDTO);
            }
        }
        return list;
    }


}
